package com.kagu.wms.module;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.CommandLine;

import com.wowza.wms.logging.WMSLogger;
import com.wowza.wms.logging.WMSLoggerFactory;
import com.xuggle.xuggler.Converter;

public class H264Transcoder extends Thread {
	private String streamName = null;
	private WMSLogger logger = WMSLoggerFactory.getLogger(H264Transcoder.class);
	private Object obj = new Object();
	private String[] args;

	class Decoder implements Runnable {
		private String bitrate;
		private String transcodedStreamName;
		private Converter converter;
		private CommandLine cmdLine;

		public Decoder(String bitrate) {
			this.bitrate = bitrate;
			transcodedStreamName = streamName + "_trance_" + bitrate;
			decoderInit();
		}

		private void decoderInit() {
			if (streamName == null || streamName.contains("_trance")
					|| streamName.contains("translation")) {
				// it's transcoded stream - so we exit to avoid the infinite
				// looping
				logger
						.info(streamName
								+ " - it's already transcoded stream - so we exit to avoid the infinite looping");
			}
			synchronized (obj) {
				args = new String[] {
						"--containerformat",
						"flv",
						"--ano",

						"--acodec",
						"libfaac",
						"--asamplerate",
						"22050",
						"--achannels",
						"1",
						"--abitrate",
						"64000",
						"--aquality",
						"0",

						"--vcodec",
						"libx264",
						"--vscalefactor",
						"1.0",
						"--vbitrate",
						bitrate+"000",
						"--vbitratetolerance",
						"12000000",
						"--vquality",
						"1",
						"--vpreset",
						getXugglePath()+"/share/ffmpeg/libx264-default.ffpreset",
						"--realtime", streamName, transcodedStreamName };

				logger.info("Creating converter object");
				converter = new Converter();
				try {
					cmdLine = converter.parseOptions(converter.defineOptions(),
							args);
				} catch (ParseException e) {
					e.printStackTrace();
				}
				obj.notify();
			}
		}

		@Override
		public void run() {
			converter.run(cmdLine);
		}
	}

	private List<Decoder> decoders = new ArrayList<Decoder>();
	private String xugglePath;

	public String getXugglePath() {
		return xugglePath;
	}

	public void setXugglePath(String xugglePath) {
		this.xugglePath = xugglePath;
	}

	public H264Transcoder(String streamName) {
		this.streamName = streamName;
	}

	public void addStreamDecoder(String bitrate) {
		decoders.add(new Decoder(bitrate));
	}

	public void run() {
		for (Decoder decoder : decoders) {
			Thread t = new Thread(decoder);
			t.start();
		}
	}

}
